import GameData_blxf from "../GameData/GameData";
import { BundleManager_blxf } from "../Manager/BundleManager";
import { CsvManager_blxf } from "../Manager/CsvManager";
import { EnumManager_blxf } from "../Manager/EnumManager";
import { PlatformManager_blxf } from "../Manager/PlatformManager";
import { ConfigModule_blxf } from "./ConfigModule";


const {ccclass, property} = cc._decorator;

/** 音效模块 */

@ccclass
export default class AudioModule_blxf {

    private constructor (){ }

    private static _AudioModule_blxf: AudioModule_blxf = new AudioModule_blxf();

    public static get instance () {
        return this._AudioModule_blxf;
    }

    /** 背景音乐音频id */
    private bgmId: number = null;
    /** 音效id */
    private audioId: number = null;
    /** 背景音乐 */
    private bgmClip: cc.AudioClip = null;


    private randomGameBgmId: string = null;

    /** 获取背景音乐音量 */
    getVolume_blxf () {
        return cc.audioEngine.getVolume( this.bgmId );
    }

    /**
     * 设置背景音乐音量
     * @param volume 
     */
    setBgmVolume_blxf ( volume: number ) {
        cc.audioEngine.setVolume(this.bgmId, volume);
    }

    /**
     * 播放背景音乐
     * @param bgmId 背景音乐id
     * @param isLoop 是否循环
     * @param startTime 起始时间
     */
    playBgm_blxf ( bgmId: string, isLoop: boolean = true, startTime: number = 0, cb: any = ()=>{} ) {
        if ( !bgmId ) return;

        let _audioData: any = CsvManager_blxf.instance.getAudioData_blxf( Number(bgmId) );
        if ( !_audioData ) return;

        let { BundleName, _audioPath } = _audioData;

        let _bundle: any = BundleManager_blxf.instance[ `Bundle_${BundleName}` ];
        if ( !_bundle ) return;

        _bundle.load( _audioPath, cc.AudioClip, ( err, clip ) => {
            if ( err ) return cc.error(`playBGM ${_audioData.AudioMsg} err ==`, err);

            if ( this.bgmClip ) {
                this.bgmClip.decRef && this.bgmClip.decRef();
                this.bgmClip = null;
            }
            this.bgmClip = clip;

            this.bgmId = cc.audioEngine.playMusic( clip, isLoop );

            this.updateBgmVolume_blxf();

            // 播放至指定时间
            let _totalTime: number = cc.audioEngine.getDuration( this.bgmId );
            let _isTime: boolean = startTime > 0 && _totalTime > startTime;
            _isTime && cc.audioEngine.setCurrentTime( this.bgmId, startTime );

            cb && cb(_totalTime, clip);

            clip.addRef && clip.addRef();
            // cc.log('playBGM clip ==>', musicPath, clip._name, clip._ref, clip);
        })
    }

    /** 更新背景音乐音量 */
    updateBgmVolume_blxf () {
        let _isOffBgm: boolean = GameData_blxf.instance.getIsOffBgm_blxf();
        let _volume: number = _isOffBgm ? 0 :ConfigModule_blxf.instance.bgmVolume;
        this.setBgmVolume_blxf( _volume );
    }

    /**
     * 播放音效
     * @param audioId 音效id 
     * @param isLoop 是否循环
     * @param cb 回调函数
     */
    playAudio_blxf ( audioId: string, isLoop: boolean = false, cb: any = ()=>{} ) {
        if ( !audioId ) return;

        // 是否已关闭音效
        let _isOffEffect: boolean = GameData_blxf.instance.getIsOffEffect_blxf();
        if ( _isOffEffect ) return;

        let _audioData: any = CsvManager_blxf.instance.getAudioData_blxf( Number(audioId) );
        if ( !_audioData ) return;

        let { BundleName, _audioPath } = _audioData;

        let _audioBundle: any = BundleManager_blxf.instance[ `Bundle_${BundleName}` ];
        if ( !_audioBundle ) return;

        _audioBundle.load( _audioPath, cc.AudioClip, ( err, clip ) => {
            if ( err ) return cc.error(`playAudio ${_audioData.AudioMsg} err ==`, err);

            // 检测是否是Android
            let _isAndroid: boolean = cc.sys.os === cc.sys.OS_ANDROID;
            let _platformName: string = ConfigModule_blxf.getPlatformName_blxf();
            let { PLATFORM_WECHAT } = EnumManager_blxf.platformType;
            if ( _platformName == PLATFORM_WECHAT && !_isAndroid ) {
                // setTimeout(()=>{ clip.decRef && clip.decRef(); }, 20 );
                return PlatformManager_blxf.instance.playAudio_blxf( clip.nativeUrl );
            }

            this.audioId = cc.audioEngine.playEffect( clip, isLoop );
            let _totalTime = cc.audioEngine.getDuration( this.audioId );
            cb && cb( this.audioId, clip, _totalTime );

            // // 资源引用（TODO 长时间释放加载或导致音效出现杂音）
            // clip.addRef && clip.addRef();
            // cc.audioEngine.setFinishCallback(this.audioId, () => {
            //     clip.decRef && clip.decRef();
            // });
            // cc.warn('_audioPath >>', _audioPath);
        });
    }

    /** 暂停播放音乐 */
    stopBgm_blxf () {
        this.bgmId != undefined && cc.audioEngine.pauseMusic();
    }

    /** 恢复播放音乐 */
    resumeBgm_blxf () {
        this.bgmId != undefined && cc.audioEngine.resumeMusic();
    }


    /** 播放主页背景音乐 */
    playMainBgm_blxf () {
        let { AUDIO_MAIN_BGM } = EnumManager_blxf.gameAudioType;
        this.playBgm_blxf( AUDIO_MAIN_BGM );
    }

    /** 随机游戏背景音乐 */
    onRandomGameBgm_blxf () {
        let { AUDIO_GAME_BGM1, AUDIO_GAME_BGM2, AUDIO_GAME_BGM3 } = EnumManager_blxf.gameAudioType;
        let _bgmList: string[] = [ AUDIO_GAME_BGM1/*, AUDIO_GAME_BGM2, AUDIO_GAME_BGM3*/ ];

        if ( this.randomGameBgmId ) {
            _bgmList = _bgmList.filter( item => item != this.randomGameBgmId );
        }

        _bgmList.sort( (a, b) => Math.random() - 0.5 );
        this.randomGameBgmId = _bgmList[0];

        this.playBgm_blxf( this.randomGameBgmId );
    }

    /** 上货 或 放入正确物品音效 */
    playShopOkAudio_xft ( addNum: number ) {
        let { AUDIO_SHOP_OK } = EnumManager_blxf.gameAudioType;
        let _audio = Number( AUDIO_SHOP_OK ) + addNum;
        this.playAudio_blxf( `${_audio}` );
    }

    /** 播放点击音效 */
    static playTouchAudio_blxf () {
        let { AUDIO_DIALOGUE } = EnumManager_blxf.gameAudioType;
        AudioModule_blxf.instance.playAudio_blxf( AUDIO_DIALOGUE );
    }

    
    /** 放置音效 */
    static playDropAudio_blxf () {
        this.playGameAudio_blxf( 102 );
    }

    /** 派发 */
    static playSendAudio_blxf () {
        this.playGameAudio_blxf( 103 );
    }

    /** 消除 */
    static playRemoveAudio_blxf () {
        this.playGameAudio_blxf( 104 );
    }

    /** 合并 */
    static playMergeAudio_blxf () {
        this.playGameAudio_blxf( 105 );
    }

    /** 解锁 */
    static playUnlockAudio_blxf () {
        this.playGameAudio_blxf( 106 );
    }

    /** 挪动 */
    static playMoveAudio_blxf () {
        this.playGameAudio_blxf( 107 );
    }

    /** 道具移除 */
    static playPropRemoveAudio_blxf () {
        this.playGameAudio_blxf( 108 );
    }

    /** 消除前 */
    static playBefroeRemoveAudio_blxf () {
        this.playGameAudio_blxf( 109 );
    }

    /** 点击宠物 */
    static playTouchPetAudio_blxf () {
        this.playGameAudio_blxf( 110 );
    }

    static playMouthAudio_blxf () {
        this.playGameAudio_blxf( 111 );
    }

    /** 空间不足 */
    static playSpaceAudio_blxf () {
        this.playGameAudio_blxf( 201 );
    }

    /** 进入关卡 */
    static playEntryPassAudio_blxf () {
        this.playGameAudio_blxf( 202 );
    }

    /** 一键喂养 */
    static playPetProgressAudio_blxf () {
        this.playGameAudio_blxf( 203 );
    }

    /** 消除多叠音效 */
    static playRemoveCombo_blxf ( comboNum: number ) {
        if ( comboNum < 2 ) return;

        switch ( comboNum ) {
            case 2 : this.playGameAudio_blxf( 210 ); break;
            default: this.playGameAudio_blxf( 211 ); 
                setTimeout(()=>{
                    this.playGameAudio_blxf( 210 );
                }, 1 * 1000);
                break;
        }
    }

    /**
     * 播放游戏音效
     * @param type 
     */
    static playGameAudio_blxf ( type: number, cb: any = ()=>{} ) {
        let {
            AUDIO_TOUCH_JENGA_BTN,
            AUDIO_TOUCH_DROP,
            AUDIO_TOUCH_SEND,
            AUDIO_TOUCH_REMOVE,
            AUDIO_TOUCH_MERGE,
            AUDIO_TOUCH_UNLOCK,
            AUDIO_TOUCH_MOVE,
            AUDIO_TOUCH_PROP_REMOVE,
            AUDIO_TOUCH_SPACE,
            AUDIO_TOUCH_NEXT_PASS,
            AUDIO_TOUCH_PET_PROGRESS,
            AUDIO_TOUCH_BEFORE_REMOVE,
            AUDIO_TOUCH_TOUCH_PET,
            AUDIO_MOUTH,
            AUDIO_REMOVE_COMBO2,
            AUDIO_REMOVE_COMBO3,
        } = EnumManager_blxf.gameAudioType;

        let _audioId: string;
        switch ( type ) {
            case 101 : _audioId = AUDIO_TOUCH_JENGA_BTN; break;
            case 102 : _audioId = AUDIO_TOUCH_DROP; break;
            case 103 : _audioId = AUDIO_TOUCH_SEND; break;
            case 104 : _audioId = AUDIO_TOUCH_REMOVE; break;
            case 105 : _audioId = AUDIO_TOUCH_MERGE; break;
            case 106 : _audioId = AUDIO_TOUCH_UNLOCK; break;
            case 107 : _audioId = AUDIO_TOUCH_MOVE; break;
            case 108 : _audioId = AUDIO_TOUCH_PROP_REMOVE; break;
            case 109 : _audioId = AUDIO_TOUCH_BEFORE_REMOVE; break;
            case 110 : _audioId = AUDIO_TOUCH_TOUCH_PET; break;
            case 111 : _audioId = AUDIO_MOUTH; break;
            case 201 : _audioId = AUDIO_TOUCH_SPACE; break;
            case 202 : _audioId = AUDIO_TOUCH_NEXT_PASS; break;
            case 203 : _audioId = AUDIO_TOUCH_PET_PROGRESS; break;
            case 210 : _audioId = AUDIO_REMOVE_COMBO2; break;
            case 211 : _audioId = AUDIO_REMOVE_COMBO3; break;
        }
        _audioId && AudioModule_blxf.instance.playAudio_blxf( _audioId, false, cb );
    }
}
